package labox.innovation.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import labox.innovation.util.L2Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ServerConfig {
    private static final Logger _log = LoggerFactory.getLogger(ServerConfig.class.getName());
    private static final String SERVER_CONFIG_FILE = "./config/server.properties";

    // --------------------------------------------------
    // Server Settings
    // --------------------------------------------------
    /**
     * 游戏服务器端口
     */
    public static int PORT_GAME;

    /**
     * 登录服务器外网端口
     */
    public static int PORT_LOGIN;

    /**
     * 登陆服务器外网地址
     */
    public static String LOGIN_BIND_ADDRESS;

    /**
     * 登陆服务器是否使用socket连接
     */
    public static boolean LOGIN_SOCKET;

    /**
     * 在被绑前登陆失败的重试次数
     */
    public static int LOGIN_TRY_BEFORE_BAN;

    /**
     * 被绑后解绑的时间（秒）
     */
    public static int LOGIN_BLOCK_AFTER_BAN;

    /**
     * 游戏服务器本地地址
     */
    public static String GAMESERVER_HOSTNAME;

    /**
     * 数据库驱动
     */
    public static String DATABASE_DRIVER;

    /**
     * 数据库地址
     */
    public static String DATABASE_URL;

    /**
     * 数据库账户
     */
    public static String DATABASE_LOGIN;

    /**
     * 数据库密码
     */
    public static String DATABASE_PASSWORD;

    /**
     * 数据库最大的连接数
     */
    public static int DATABASE_MAX_CONNECTIONS;

    /**
     * 数据库连接最大的空闲时间
     */
    public static int DATABASE_MAX_IDLE_TIME;

    /**
     * 最大在线用户数
     */
    public static int MAXIMUM_ONLINE_USERS;

    /**
     * 玩家取名的正则表达式格式模板（详见server.properties）
     */
    public static String CNAME_TEMPLATE;

    /**
     * 宠物取名的正则表达式格式模板（详见server.properties）
     */
    public static String PET_NAME_TEMPLATE;

    /**
     * 每个账户拥有的最大的角色数量
     */
    public static int MAX_CHARACTERS_NUMBER_PER_ACCOUNT;

    /**
     * 数据包的根路径
     */
    public static File DATAPACK_ROOT;

    /**
     * 是否允许服务器的ID被修改
     */
    public static boolean ACCEPT_ALTERNATE_ID;

    /**
     * 游戏服务器的向登陆服务器请求的唯一标示ID
     */
    public static int REQUEST_ID;

    /**
     * 连接服务器所需的最小协议版本号
     */
    public static int MIN_PROTOCOL_REVISION;

    /**
     * 连接服务器所需的最大的协议版本号
     */
    public static int MAX_PROTOCOL_REVISION;

    /**
     * 连接服务器所需的最小客户端版本号
     */
    public static int MIN_CLIENT_REVISION;
    /**
     * 游戏服务器最终从登陆服务器获取的服务器ID
     */
    public static int SERVER_ID;

    /**
     * 连接服务器所需的最大的客户端版本号
     */
    public static int MAX_CLIENT_REVISION;

    public static String GAME_HOST_NAME;

    /**
     * 服务器外部地址显示在登录服务器下发的列表中的地址
     */
    public static String EXTERNAL_HOSTNAME;

    /**
     * 服务器内部地址显示在登录服务器下发的列表中的地址
     */
    public static String INTERNAL_HOSTNAME;

    /**
     * 路由器地址
     */
    public static String ROUTER_HOSTNAME;
    /**
     * 游戏服务器连接登陆服务器的地址（内网地址）
     */
    public static String GAME_SERVER_LOGIN_HOST;

    /**
     * 游戏服务器连接登陆服务器的端口（内网端口）
     */
    public static int GAME_SERVER_LOGIN_PORT;

    public static void load() {
        _log.info("Loading server Configuration Files...", Config.SERVER_ID);
        InputStream is = null;
        try {
            L2Properties serverSettings = new L2Properties();
            is = new FileInputStream(new File(SERVER_CONFIG_FILE));
            serverSettings.load(is, "UTF-8");

            GAMESERVER_HOSTNAME = serverSettings.getProperty("GameserverHostname");
            PORT_GAME = Integer.parseInt(serverSettings.getProperty("GameserverPort", "8014"));

            EXTERNAL_HOSTNAME = serverSettings.getProperty("ExternalHostname", "*");
            INTERNAL_HOSTNAME = serverSettings.getProperty("InternalHostname", "*");

            GAME_SERVER_LOGIN_PORT = Integer.parseInt(serverSettings.getProperty("LoginPort", "9014"));
            GAME_SERVER_LOGIN_HOST = serverSettings.getProperty("LoginHost", "*");

            SERVER_ID = REQUEST_ID = Integer.parseInt(serverSettings.getProperty("RequestServerID", "0"));
            ACCEPT_ALTERNATE_ID = Boolean.parseBoolean(serverSettings.getProperty("AcceptAlternateID", "True"));

            DATABASE_DRIVER = serverSettings.getProperty("Driver", "com.mysql.jdbc.Driver");
            DATABASE_URL = serverSettings.getProperty("URL", "jdbc:mysql://localhost/inndb");
            DATABASE_LOGIN = serverSettings.getProperty("Login", "root");
            DATABASE_PASSWORD = serverSettings.getProperty("Password", "root");
            DATABASE_MAX_CONNECTIONS = Integer.parseInt(serverSettings.getProperty("MaximumDbConnections", "10"));
            DATABASE_MAX_IDLE_TIME = Integer.parseInt(serverSettings.getProperty("MaximumDbIdleTime", "0"));

            DATAPACK_ROOT = new File(serverSettings.getProperty("DatapackRoot", ".")).getCanonicalFile();
            CNAME_TEMPLATE = serverSettings.getProperty("CnameTemplate", ".*");
            PET_NAME_TEMPLATE = serverSettings.getProperty("PetNameTemplate", ".*");

            MAX_CHARACTERS_NUMBER_PER_ACCOUNT = Integer.parseInt(serverSettings.getProperty("CharMaxNumber", "0"));
            MAXIMUM_ONLINE_USERS = Integer.parseInt(serverSettings.getProperty("MaximumOnlineUsers", "100"));

            MIN_CLIENT_REVISION = Integer.parseInt(serverSettings.getProperty("MinClientRevision", "0"));
            MAX_CLIENT_REVISION = Integer.parseInt(serverSettings.getProperty("MaxClientRevision", "0"));

            GAME_HOST_NAME = serverSettings.getProperty("GameHostname", "乾坤服务器");

            if (MIN_CLIENT_REVISION > MAX_CLIENT_REVISION) {
                throw new Error("MinClientRevision is bigger than MaxClientRevision in server configuration file.");
            }
        } catch (Exception e) {
            _log.error("Failed to Load " + SERVER_CONFIG_FILE + " File.", e);
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                _log.error("InputStream close occured IOException");
            }
        }
    }
}
